Solidity の ecrecover を使用して署名者のアドレスを取得する
署名検証の手順
1. 検証するメッセージと署名を用意します。
2. メッセージから Keccak ハッシュを得ます
3. ecrecover を使用して、メッセージのハッシュ、v, r, s から署名者の公開鍵を得ます。
4. ecrecover により得られた公開鍵から Ethereum アドレスを計算し、実際の署名者のアドレスと比較します。
サンプルコード
code:example.sol
pragma solidity 0.4.24;
contract ecrecoverTest {
string public MSG = "piyopiyo!";
address public SIGNER_ADDRESS = 0x89c24a88bad4abe0a4f5b2eb5a86db1fb323832c;
bytes32 public R = 0xdd7fa0d0b259468434cf14760c6607f36f2d7429feaaaedf6d86265c11098d20;
bytes32 public S = 0x14cf83d2204e50b12fcb2445a70c214509d0f4edf0e0ee6e8d18fed8fbb146c0;
uint8 public V = 27;
constructor () public {
}
function verify() public view returns (bool) {
bytes32 msgHash = keccak256(bytes(MSG));
// => 0xb826be27896975a66f168f81f553fe0b2f87599d63d01c3b93c1a8a6f2243e5d
address signer = ecrecover(msgHash, V, R, S);
// => 0x89c24a88bad4abe0a4f5b2eb5a86db1fb323832c
if (signer == SIGNER_ADDRESS) {
return true;
} else {
return false;
}
}
}
Note
web3.eth.sign を使用して sign をした場合は、上記コードの msgHash に対して、さらに "\x19Ethereum Signed Message:\n32" というプレフィックスをつけたものの keccak256 ハッシュを得る必要があるようです。 関連
JavaScript で署名検証をする手順はこちら